package com.liph.config;

import com.liph.hander.MyAuthenticationFailHandler;
import com.liph.hander.MyAuthenticationSuccessHandler;
import com.liph.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @author lipenghui
 * @date 2022-12-06
 * @description 设置用户名密码方式三：继承PasswordEncoderFactories，重写configure
 */
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserService userService;

    /***
     * @author lipenghui
     * @date 2022/12/6
     * @param []
     * @description 指定一种密码加密方式，更多方式参考PasswordEncoderFactories
     **/
    @Bean
    public PasswordEncoder passwordEncoder() {
        // noop为不加密方式
//        return NoOpPasswordEncoder.getInstance();

        // "bcrypt" 为官方推荐方式
        return new BCryptPasswordEncoder();
    }


    /***
     * @author lipenghui
     * @date 2022/12/6
     * @param [auth]
     * @description  如果与方式二同时存在，则以方式三为准
     **/
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 以下方式，都是将用户名和密码存入内存中

        // 方式一：设置UserDetailsService
        auth.userDetailsService(userService);

        // 方式二：
//        auth.inMemoryAuthentication()
//                .withUser("fox4")
//                .password(passwordEncoder().encode("123456"))
//                .authorities("admin");

    }


    /***
     * @author lipenghui
     * @date 2022/12/8
     * @param [http]
     * @description 自定义登录页面设置
     **/
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 认证
        http.formLogin() // 表单提交
                .loginPage("/login.html") // 自定义登录页面
                .loginProcessingUrl("/user/login") // 登录访问路径，必须和表单提交接口一样
//                .defaultSuccessUrl("/main.html"); // 登录成功后有多种处理方式，如跳转页面
//                .successForwardUrl("/main")   //认证成功之后转发的路径,必须是Post请求
//                .failureForwardUrl("/toerror");  //认证失败之后转发的路径,必须是Post请求
                .successHandler(new MyAuthenticationSuccessHandler("/main.html")) // 自定义hander认证成功后跳转页面
                .failureHandler(new MyAuthenticationFailHandler("/error.html")); // 自定义hander认证失败后跳转页面

        // （授权）需要设置哪些路径需要认证，哪些不需要，如不设置，默认不需要认证
        http.authorizeRequests()
                .antMatchers("/login.html", "/user/login", "/error.html").permitAll() // 不需要认证
                .anyRequest().authenticated() // 需要认证
                .and().csrf().disable(); // csrf保护禁用

    }
}

